//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
// SPN.H
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
#ifndef _SPN_H
#define _SPN_H

//-----------------------------------------------
// Suspect Parameter Numbers (SPN)
//-----------------------------------------------
/* The SPN is a 19-bit number and has a range from 0 to 52487.  For proprietary parameters a range from 52192 to 52487
   is reserved. */
//===============================================
// Each separate variable within the whole ETS
// system has its own SPN.  The valid SPN range
// for MY_ is 8000 to 52191.  SPN's less than
// 8000 are defined in the J1939 specification.
//===============================================
typedef enum {
	// Never sent on the CAN bus
	SPN_INVALID = 0,

	// From the J1939 specification
	SPN_COMPASS_BEARING = 165,
	SPN_BATTERY_POTENTIAL = 168,						// Battery voltage
	SPN_AMBIENT_AIR_TEMPERATURE = 171,					// MY_ Use SPN_AMBIENT_TEMPERATURE instead
	SPN_ENGINE_AIR_INTAKE_TEMPERATURE = 172,
	SPN_ENGINE_FUEL_TEMPERATURE_LEFT_BANK_1 = 174,
	SPN_ENGINE_FUEL_TEMPERATURE_RIGHT_BANK_2 = 3468,
	SPN_ENGINE_SPEED = 190,
	SPN_SOFTWARE_IDENTIFICATION = 234,
	SPN_AUXILARY_TEMPERATURE_1 = 441,
	SPN_AUXILARY_TEMPERATURE_2 = 442,
	SPN_NAVIGATION_BASED_VEHICLE_SPEED = 517,
	SPN_ALTITUDE = 580,
	SPN_PITCH = 583,
	SPN_LATITUDE = 584,
	SPN_LONGITUDE = 585,
	SPN_MAKE = 586,										// Make = "MY_"
	SPN_MODEL = 587,									// Model = "AFRC", "EMD", etc.
	SPN_SERIAL_NUMBER = 588,
	SPN_OUTPUT_SHAFT_SPEED = 1623,
	SPN_TACHOGRAPH_VEHICLE_SPEED = 1624,

	SPN_EXHAUST_GAS_SENSOR_IS_AT_TEMPERATURE_LEFT_BANK_1 = 3219,
	SPN_O2_READING_IS_STABLE_LEFT_BANK_1 = 3221,

	SPN_NOX = 3226,
	SPN_O2 = 3227,
	SPN_AFTERTREATMENT_1_INTAKE_DEW_POINT = 3237,

	SPN_EXHAUST_GAS_SENSOR_IS_AT_TEMPERATURE_RIGHT_BANK_2 = 3258,
	SPN_O2_READING_IS_STABLE_RIGHT_BANK_2 = 3260,
	SPN_EXHAUST_TEMPERATURE_PRECAT_LEFT_BANK_1 = 3241,
	SPN_EXHAUST_TEMPERATURE_POSTCAT_LEFT_BANK_1 = 3245,

	// Mistake in the original PGN.H - this is the correct version
	SPN_EXHAUST_TEMPERATURE_PRECAT = SPN_EXHAUST_TEMPERATURE_PRECAT_LEFT_BANK_1,
	SPN_EXHAUST_TEMPERATURE_POSTCAT = SPN_EXHAUST_TEMPERATURE_POSTCAT_LEFT_BANK_1,

	SPN_ENGINE_OPERATING_STATE = 3543,
	SPN_TIME_REMAINING_IN_ENGINE_OPERATING_STATE = 3544,
	SPN_O2_SENSOR_CLOSED_LOOP_OPERATION_LEFT_BANK_1 = 4240,
	SPN_O2_SENSOR_CLOSED_LOOP_OPERATION_RIGHT_BANK_2 = 4241,
	SPN_DPV_DESIRED_POSITION_LEFT_BANK_1 = 5276,
	SPN_DPV_ACTUAL_POSITION_LEFT_BANK_1 = 5277,
	SPN_DPV_DESIRED_POSITION_RIGHT_BANK_2 = 5278,
	SPN_DPV_ACTUAL_POSITION_RIGHT_BANK_2 = 5279,

	// GMT Time
	SPN_SECONDS = 959,									// Seconds in the current time of day
	SPN_MINUTES = 960,
	SPN_HOURS = 961,
	SPN_DAY = 962,
	SPN_MONTH = 963,
	SPN_YEAR = 964,
	SPN_LOCAL_MINUTE_OFFSET = 1601,
	SPN_LOCAL_HOUR_OFFSET = 1602,

	//------------------------------------------------------------------------------------------------
	// Proprietary Configuration SPN's: 8000 to 9000
	//------------------------------------------------------------------------------------------------

	// Do not change the order of this section
	SPN_AUTO_MANUAL_MODE = 8000,			// 8000

	// Left Sensor
	SPN_LEFT_WIDEBAND_LAMBDA_SETPOINT,
	SPN_LEFT_NARROWBAND_VOLTAGE_SETPOINT,
	SPN_LEFT_WIDEBAND_KP,					// 8003
	SPN_LEFT_WIDEBAND_KI,
	SPN_LEFT_WIDEBAND_KD,
	SPN_LEFT_NARROWBAND_KP,					// 8006
	SPN_LEFT_NARROWBAND_KI,
	SPN_LEFT_NARROWBAND_KD,
	SPN_LEFT_NERNST_KP,
	SPN_LEFT_NERNST_KI,						// 8010
	SPN_LEFT_NERNST_KD,

	SPN_MINIMUM_RPM,
	SPN_MAXIMUM_RPM,
	SPN_MINIMUM_EXHAUST_TEMPERATURE,
	SPN_MAXIMUM_EXHAUST_TEMPERATURE,		// 8015
	SPN_O2_SENSOR_TYPE,						// 8016
	NOT_USED_1,
	NOT_USED_2,
	SPN_O2_SENSOR_ERROR_TIME,
	SPN_FILESYSTEM_UPDATE_PERIOD_S,			// 8020
	SPN_DATALOGGING_PERIOD_S,
	SPN_ANALOG_1_IS_4_20MA,
	SPN_ANALOG_2_IS_4_20MA,
	SPN_MANIFOLD_PRESSURE_RIGHT_IS_4_20MA,	// 8024
	SPN_MANIFOLD_PRESSURE_LEFT_IS_4_20MA,
	SPN_RS232_RS485_BAUD_RATE,
	SPN_O2_SENSOR_WARMUP_TIME_S,
	SPN_STARTUP_WAIT_TIME,
	SPN_HEATER_DUTY_CYCLE_BANK_1,
	SPN_HEATER_CONTROL_TIME_BANK_1,			// 8030
	SPN_HEATER_PID_ENABLED_BANK_1,
	SPN_HEATER_PID_STATE_BANK_1,
	SPN_HEATER_DUTY_CYCLE_BANK_2,
	SPN_HEATER_CONTROL_TIME_BANK_2,
	SPN_HEATER_PID_ENABLED_BANK_2,
	SPN_HEATER_PID_STATE_BANK_2,
	SPN_HEATER_DUTY_CYCLE_POSTCAT,
	SPN_HEATER_CONTROL_TIME_POSTCAT,
	SPN_HEATER_PID_ENABLED_POSTCAT,
	SPN_HEATER_PID_STATE_POSTCAT,			// 8040

	// Right Sensor
	SPN_RIGHT_WIDEBAND_LAMBDA_SETPOINT,			// 8041
	SPN_RIGHT_NARROWBAND_VOLTAGE_SETPOINT,
	SPN_RIGHT_WIDEBAND_KP,						// 8043
	SPN_RIGHT_WIDEBAND_KI,
	SPN_RIGHT_WIDEBAND_KD,
	SPN_RIGHT_NARROWBAND_KP,					// 8046
	SPN_RIGHT_NARROWBAND_KI,
	SPN_RIGHT_NARROWBAND_KD,
	SPN_RIGHT_NERNST_KP,
	SPN_RIGHT_NERNST_KI,						// 8050
	SPN_RIGHT_NERNST_KD,

	// Post Catalyst Sensor
	SPN_POSTCAT_WIDEBAND_LAMBDA_SETPOINT,		// 8052
	SPN_POSTCAT_NARROWBAND_VOLTAGE_SETPOINT,
	SPN_POSTCAT_WIDEBAND_KP,
	SPN_POSTCAT_WIDEBAND_KI,
	SPN_POSTCAT_WIDEBAND_KD,
	SPN_POSTCAT_NARROWBAND_KP,
	SPN_POSTCAT_NARROWBAND_KI,
	SPN_POSTCAT_NARROWBAND_KD,
	SPN_POSTCAT_NERNST_KP,						// 8060
	SPN_POSTCAT_NERNST_KI,
	SPN_POSTCAT_NERNST_KD,

	// All
	SPN_DPV_HOME_POSITION,						// 8063
	SPN_DPV_HOME_POSITION_STEPS,				// 8064
	SPN_DPV_DESIRED_POSITION_LEFT_BANK_1_STEPS,
	SPN_DPV_ACTUAL_POSITION_LEFT_BANK_1_STEPS,
	SPN_DPV_DESIRED_POSITION_RIGHT_BANK_2_STEPS,
	SPN_DPV_ACTUAL_POSITION_RIGHT_BANK_2_STEPS,	// 8068
	SPN_EXHAUST_DIFFERENTIAL_TEMPERATURE,
	SPN_NUMBER_OF_TEETH_ON_FLYWHEEL,			// 8070
	SPN_SETPOINT_OFFSET,						// 8071
	SPN_PID_RESPONSE_TIME_LEFT_BANK_1,
	SPN_PID_RESPONSE_TIME_RIGHT_BANK_2,

	SPN_AFRC_CONTROL_STATUS = 8100,				// 8100
	SPN_AFRC_CONTROL_STATUS_BANK_1,				// 8101
	SPN_AFRC_CONTROL_STATUS_BANK_2,				// 8102
	SPN_AFRC_CONTROL_STATUS_POSTCAT,			// 8103
	SPN_CALIBRATE_DPV_HOME_POSITION,			// 8104
	SPN_HOME_POSITION_CALIBRATION_COUNTER,		// 8105
	SPN_ENABLE_AUTOCONTROL_MODE,				// 8106

	// SPN's: 9000 and up
	SPN_APPLICATION_ID = 9000,							// 9000
	SPN_HARDWARE_ID,
	SPN_LEFT_BANK_ENABLED,								// 9002
	SPN_RIGHT_BANK_ENABLED,
	SPN_POSTCAT_ENABLED,
	SPN_SINGLE_OR_DUAL_BANK,							// 9005
	RESERVED_9,											// Was SPN_EXHAUST_TEMPERATURE_POSTCAT
	SPN_FUEL_TEMPERATURE,
	SPN_AMBIENT_TEMPERATURE,							// 9008
	SPN_SPARE0_TEMPERATURE,
	SPN_SPARE1_TEMPERATURE,								// 9010
	SPN_WIDEBAND_LAMBDA_LEFT_BANK_1,					// 9011
	SPN_WIDEBAND_LAMBDA_RIGHT_BANK_2,
	SPN_WIDEBAND_LAMBDA_POSTCAT,
	SPN_ECU_UPTIME,										// 9014 Time since last power cycle
	SPN_ECU_RUNTIME,									// 9015 Total time
	SPN_ENGINE_UPTIME,									// 9016 Time since started
	SPN_ENGINE_RUNTIME,									// 9017 Total time
	RESERVED_5,		// Orignal SPN was deleted.  This is required to maintain numbering system.
	RESERVED_6,		// Orignal SPN was deleted.  This is required to maintain numbering system.
	RESERVED_7,		// Orignal SPN was deleted.  This is required to maintain numbering system.	// 9020									// 9020
	SPN_WIDEBAND_NERNST_VOLTAGE_LEFT_BANK_1,
	SPN_WIDEBAND_NERNST_VOLTAGE_RIGHT_BANK_2,
	SPN_WIDEBAND_NERNST_VOLTAGE_POSTCAT,
	RESERVED_8,											// 9024 (was SPN_ENGINE_RPM which is duplicated by SPN_ENGINE_SPEED)
	SPN_O2_SENSOR_STATUS_LEFT_BANK_1,
	SPN_O2_SENSOR_STATUS_RIGHT_BANK_2,
	SPN_O2_SENSOR_STATUS_POSTCAT,
	SPN_CONTROL_SYSTEM_STATUS,
	SPN_SUPPLY_VOLTAGE,									// 9029 Battery voltage
	SPN_OIL_PRESSURE,									// 9030
	SPN_WIDEBAND_NERNST_CELL_RESISTANCE_LEFT_BANK_1,	// 9031
	SPN_WIDEBAND_NERNST_CELL_RESISTANCE_RIGHT_BANK_2,	// 9032
	SPN_WIDEBAND_NERNST_CELL_RESISTANCE_POSTCAT,		// 9033
	SPN_PROPRIETARY_SERIAL_NUMBER,								// 9034
	SPN_LED_INDICATORS,									// 9035
	SPN_MANIFOLD_PRESSURE_LEFT_BANK_1,					// 9036
	SPN_MANIFOLD_PRESSURE_RIGHT_BANK_2,					// 9037
	SPN_NARROWBAND_VOLTAGE_LEFT_BANK_1,					// 9038
	SPN_NARROWBAND_VOLTAGE_RIGHT_BANK_2,				// 9039
	SPN_O2_SENSOR_CLOSED_LOOP_OPERATION_POSTCAT,		// 9040
	SPN_EXHAUST_GAS_SENSOR_IS_AT_TEMPERATURE_POSTCAT,
	SPN_O2_READING_IS_STABLE_POSTCAT,
	SPN_NARROWBAND_VOLTAGE_POSTCAT,						// 9043
	SPN_DTC_STATUS_LEDS,								// 9044
	SPN_DTC_SPN,										// 9045
	SPN_AUTOSTART,
	SPN_AUTOSTART_DELAY,								// 9047
	SPN_AUTOSTART_RETRIES,
	SPN_RESERVED,
	SPN_ADAPTIVE_GAIN_LOWEST_VALUE,						// 9050
	SPN_NEVER_GIVE_UP,
	SPN_RUN_SIGNAL,										// 9052
	SPN_USE_POST_CATALYST_SENSOR,						// 9053
	SPN_ERROR_RELAY,									// 9054
	SPN_DISCRETE_INPUT,									// 9055
	SPN_OIL_PRESSURE_SWITCH,							// 9056
	SPN_TEMPERATURE_CONFIG_C_OR_F,						// 9057

	// EMD Analog Inputs
	SPN_FUELFLOW_VOLTAGE = 9100,						// 9100
	SPN_FUELFLOW_CURRENT,
	SPN_ANALOG_VOLTAGE_1,								// 9102
	SPN_ANALOG_CURRENT_1,
	SPN_ANALOG_VOLTAGE_2,
	SPN_ANALOG_CURRENT_2,
	SPN_ANALOG_VOLTAGE_3,
	SPN_ANALOG_CURRENT_3,
	SPN_ANALOG_VOLTAGE_4,
	SPN_ANALOG_CURRENT_4,
	SPN_ANALOG_VOLTAGE_5,								// 9010
	SPN_ANALOG_CURRENT_5,
	SPN_CAT_PRESSURE_VOLTAGE,
	SPN_CAT_PRESSURE_CURRENT,
	SPN_AMBIENT_TEMPERATURE_THERMISTOR,					// 9114
	SPN_FUEL_TEMPERATURE_THERMISTOR,
	SPN_ANALOG_VOLTAGE_6,								// 9116
	SPN_ANALOG_CURRENT_6,
	SPN_ANALOG_VOLTAGE_7,
	SPN_ANALOG_CURRENT_7,
	SPN_ANALOG_VOLTAGE_8,								// 9120
	SPN_ANALOG_CURRENT_8,
	SPN_ANALOG_VOLTAGE_9,
	SPN_ANALOG_CURRENT_9,
	SPN_ANALOG_VOLTAGE_10,
	SPN_ANALOG_CURRENT_10,								// 9125
	SPN_ANALOG_3_IS_4_20MA,
	SPN_ANALOG_4_IS_4_20MA,
	SPN_ANALOG_5_IS_4_20MA,
	SPN_ANALOG_6_IS_4_20MA,
	SPN_ANALOG_7_IS_4_20MA,
	SPN_ANALOG_8_IS_4_20MA,
	SPN_ANALOG_9_IS_4_20MA,
	SPN_ANALOG_10_IS_4_20MA,

	// Combined bit-field SPN's
	SPN_SENSOR_STATUS_LEFT_BANK_1_1 = 9200,
	SPN_SENSOR_STATUS_RIGHT_BANK_2_1,
	SPN_SENSOR_STATUS_POSTCAT_1,
	SPN_SENSOR_STATUS_LEFT_BANK_1_2,
	SPN_SENSOR_STATUS_RIGHT_BANK_2_2,
	SPN_SENSOR_STATUS_POSTCAT_2,						// 9205

	SPN_MULTISETPOINT_TABLE_SETUP = 9299,
	SPN_MULTISETPOINT_TABLE_CONFIG = 9300,				// 9300
	SPN_MULTISETPOINT_TABLE_LEFT_OR_RIGHT,
	SPN_MULTISETPOINT_TABLE_SOURCE,
	SPN_MULTISETPOINT_TABLE_ENTRY_0_INPUT,
	SPN_MULTISETPOINT_TABLE_ENTRY_0_OFFSET,
	SPN_MULTISETPOINT_TABLE_ENTRY_1_INPUT,
	SPN_MULTISETPOINT_TABLE_ENTRY_1_OFFSET,
	SPN_MULTISETPOINT_TABLE_ENTRY_2_INPUT,
	SPN_MULTISETPOINT_TABLE_ENTRY_2_OFFSET,
	SPN_MULTISETPOINT_TABLE_ENTRY_3_INPUT,
	SPN_MULTISETPOINT_TABLE_ENTRY_3_OFFSET,				// 9310
	SPN_MULTISETPOINT_TABLE_ENTRY_4_INPUT,
	SPN_MULTISETPOINT_TABLE_ENTRY_4_OFFSET,
	SPN_MULTISETPOINT_TABLE_ROW_0_ENABLED,
	SPN_MULTISETPOINT_TABLE_ROW_1_ENABLED,
	SPN_MULTISETPOINT_TABLE_ROW_2_ENABLED,
	SPN_MULTISETPOINT_TABLE_ROW_3_ENABLED,
	SPN_MULTISETPOINT_TABLE_ROW_4_ENABLED,

	// Temperature Gain and Offset
	SPN_EXHAUST_TEMPERATURE_PRECAT_GAIN = 9400,			// 9400
	SPN_EXHAUST_TEMPERATURE_PRECAT_OFFSET,
	SPN_EXHAUST_TEMPERATURE_POSTCAT_GAIN,
	SPN_EXHAUST_TEMPERATURE_POSTCAT_OFFSET,
	SPN_RAW_ADC_NERNST_1,								// 9404
	SPN_RAW_ADC_WIDEBAND_1,
	SPN_RAW_ADC_NARROWBAND_1,
	SPN_RAW_ADC_NERNST_2,
	SPN_RAW_ADC_WIDEBAND_2,
	SPN_RAW_ADC_NARROWBAND_2,
	SPN_RAW_ADC_NERNST_POSTCAT,							// 9410
	SPN_RAW_ADC_WIDEBAND_POSTCAT,
	SPN_DATATAG_STATUS_ENGINE,
	SPN_DATATAG_STATUS_COOLER,
	SPN_DATATAG_STATUS_COMPRESSOR,
	SPN_NOX_SENSOR_STATUS,
	SPN_NOX_HEATER,
	SPN_NOX_ERROR,
	SPN_O2_ERROR,
	SPN_DEW_POINT,		// Combination of 4 J1939 SPN's	
	SPN_UNUSED_8,										// 9420
	SPN_UNUSED_16,
	SPN_UNUSED_32,
	SPN_AUTOCONTROL_ADJUSTMENT,
	SPN_AUTOCONTROL_MINIMUM_POSTCAT_VOLTS,
	SPN_AUTOCONTROL_TARGET_AQUISITION_TIME,
	SPN_AUTOCONTROL_TARGET_HOLD_TIME,
	SPN_RAW_ADC_NARROWBAND_POSTCAT,						// 9427

	SPN_X,
	SPN_Y, 
	SPN_STRING,
	
	SPN_REG_PRECAT_TEMPERATURE_4_HOUR_AVERAGE = 10000,
	SPN_REG_DIFFERENTIAL_PRESSURE_15_MINUTE_AVERAGE,

	// Production Test Support - these should be the last SPNs in this list
	SPN_PRODUCTION_TEST_STATE_SLAVE = 0x8000,			// 32768
	SPN_PRODUCTION_TEST_SELECT_DPV,
	SPN_PRODUCTION_TEST_SET_DPV_PHASE,					// Byte 0 = Phase A,B,C,D
	SPN_PRODUCTION_TEST_SELECT_HEATER,					// Byte 0 = L/R
	SPN_PRODUCTION_TEST_SET_SENSOR_HEATER_PWM,			// 0-100% 16-bit float
	SPN_PRODUCTION_TARGET_TEMPERATURE,
	SPN_PRODUCTION_OK_TO_CALIBRATE,
	SPN_PRODUCTION_CALIBRATED,
	SPN_PRODUCTION_TEST_STATE_MASTER,
} spnEnumType;

//-----------------------------------------------
// SLOT identifier
//-----------------------------------------------
typedef enum {
	PROPRIETARY_GAIN1,
	PROPRIETARY_VOLT1,
	PROPRIETARY_CURRENT1,
	PROPRIETARY_TEXT,
	PROPRIETARY_LAMBDA,
	PROPRIETARY_LAMBDA_OFFSET,
	PROPRIETARY_STATUS,					// 2 bits - see SPN 595
	PROPRIETARY_SENSOR_TYPE,				// 2 bits: 00=NARROWBAND, 01=WIDEBAND, 10 & 11 reserved
	PROPRIETARY_BAUDRATE,
	PROPRIETARY_CLOSED_LOOP_STATUS,		// 4 bits - see SPN 4240
	PROPRIETARY_U8,
	PROPRIETARY_U16,
	PROPRIETARY_U32,						// 4 bytes
	PROPRIETARY_U64,						// 8 bytes - used for serial numbers
	PROPRIETARY_2BYTE_FLOAT,
	PROPRIETARY_4BYTE_FLOAT,
	PROPRIETARY_PRESSURE_PSI,
	PROPRIETARY_PRESSURE_HG,
	PROPRIETARY_MS_TO_SECONDS,
	PROPRIETARY_CONTROL_STATUS,			// 1 byte - See controlStatusEnumType
	PROPRIETARY_SENSOR_STATUS,				// 1 byte - See sensorStatusEnumType
	PROPRIETARY_SPN,						// 2 bytes
	PROPRIETARY_MULTISETPOINT_CONFIG,		// 1 byte - See multisetpointConfigEnumType
	PROPRIETARY_MULTISETPOINT_SETUP,		// 6 bytes - See mstSetupType
	PROPRIETARY_TEMPERATURE,				// 2 bytes - C or F with same scaling
	PROPRIETARY_TEMPERATURE_OFFSET,		// 2 bytes - C or F with same scaling, without +32 internal conversion
	PROPRIETARY_NOX_SENSOR_STATUS,
	PROPRIETARY_NOX_HEATER_STATUS,
	PROPRIETARY_NOX_FMI,
	PROPRIETARY_O2_FMI,
	PROPRIETARY_DEW_POINT,
	PROPRIETARY_STRING,

	// From J1939 documentation
	SAE_AD02,
	SAE_AD05,
	SAE_DS06,
	SAE_PP01,						// Parts Per Million 0.05 ppm/bit -200 to 3012.75 ppm -200 ppm 2 bytes 236
	SAE_PC16,						// Percent, concentration 0.000514 %/bit -12% to 21% -12 % 2 bytes 237
	SAE_TP02,
	SAE_PC01,
	SAE_PC03,
	SAE_PC04,
	SAE_PC07,
	SAE_EV01,
	SAE_TM02,
	SAE_TM04,
	SAE_TM05,
	SAE_TM08,
	SAE_TM09,
	SAE_TM11,
	SAE_VL02,
	SAE_VR01,
	SAE_CD01,
	SAE_CM01,
	SAE_CY01,
	SAE_CT05,
	SAE_RS01,
	LAST_SLOT_TYPE=SAE_RS01,
} slotEnumType;
#define LAST_SLOT_INDEX	(LAST_SLOT_TYPE-1)

#define MAX_UNITS_LABEL_LENGTH	8
typedef struct {
	slotEnumType slotIdentifier;
	char label[MAX_UNITS_LABEL_LENGTH+1];
	int bytes;
	float gain;
	float offset;
	float minimum;
	float maximum;
} slotType;

#define MY_0_100_SCALING				0.0025
#define MY_0_100_OFFSET				0.0
#define MY_gain1_SCALING				0.001
//#define MY_gain1_OFFSET				-32.767	// Can't get this to fit within 16 bits all the way through to the PC CAN HMI
#define MY_gain1_OFFSET				-16.384
#define MY_volt1_SCALING				0.0001	// 0-6.5535V
#define MY_volt1_OFFSET				0.0
#define MY_current1_SCALING			0.00001	// 0-655.35mA, 0-0.65535A
#define MY_current1_OFFSET				0.0
#define MY_text_SCALING				0
#define MY_text_OFFSET					0.0
#define EMTlambda_SCALING				0.0001
#define EMTlambda_OFFSET				0.0
#define EMTlambda_Off_SCALING			0.00001		// 0.32768 to -0.32767
#define EMTlambda_Off_OFFSET			-0.32767
#define SAEad02_SCALING					0.1
#define SAEad02_OFFSET					-3276.8
#define SAEad05_SCALING					0.0078125	//(1.0/128.0)
#define SAEad05_OFFSET					0.0
#define SAEds06_SCALING					0.125
#define SAEds06_OFFSET					-2500.0
#define SAEtp02_SCALING					0.03125	// -273 to 1775C
#define SAEtp02_OFFSET					-273.0	// Subtract offset here, add when decoding on CAN RX side
#define SAEpc01_SCALING					0.0025
#define SAEpc01_OFFSET					0.0
#define SAEpc03_SCALING					0.4
#define SAEpc03_OFFSET					0.0
#define SAEpc04_SCALING					0.8
#define SAEpc04_OFFSET					-100.0
#define SAEpc07_SCALING					0.1
#define SAEpc07_OFFSET					-100.0
#define SAEev01_SCALING					0.05
#define SAEev01_OFFSET					0.0
#define SAEev03_SCALING					0.01
#define SAEev03_OFFSET					0.0
#define SAEtm02_SCALING					0.001
#define SAEtm02_OFFSET					0.0
#define SAEtm04_SCALING					0.25
#define SAEtm04_OFFSET					0.0
#define PROPRIETARY_MS2S_SCALING				250.0
#define PROPRIETARY_MS2S_OFFSET				0.0
#define SAEtm09_SCALING					0.000277777	// (1.0/3600)	// 1 bit per second
#define SAEtm09_OFFSET					0.0
#define SAEvr01_SCALING					0.125
#define SAEvr01_OFFSET					0.0
#define SAEvl02_SCALING					0.00390625	// (1.0/256.0)
#define SAEvl02_OFFSET					0.0
#define SAEct03_SCALING					1
#define SAEct03_OFFSET					0.0
#define SAEct05_SCALING					1
#define SAEct05_OFFSET					0.0
#define SAEct07_SCALING					1
#define SAEct07_OFFSET					0.0
#define SAEbs08_SCALING					0
#define SAEbs08_OFFSET					0.0
#define SAEfg01_SCALING					0.05		// kg/hr
#define SAEfg01_OFFSET					0.0
#define SAErs01_SCALING					0.1			// Resistance in ohms
#define SAErs01_OFFSET					0.0

#define SAEpp01_SCALING					0.05
#define SAEpp01_OFFSET					-200.0
#define SAEpc16_SCALING					0.000514
#define SAEpc16_OFFSET					-12.0

// 2011/06/02: This is 4-20mA current device until further notice.
#define MY_pressure_psi_SCALING			MY_current1_SCALING
#define MY_pressure_psi_OFFSET				MY_current1_OFFSET
#define MY_pressure_hg_SCALING				MY_current1_SCALING
#define MY_pressure_hg_OFFSET				MY_current1_OFFSET

// "magic number" that indicates the minimum or maximum value is to be ignored.
#define float_IGNORE					1.1111

#ifdef GLOBAL
	const slotType slotTable[] = {
		// Index,				Labelxxx,	bytes,	gain,					offset,							minimum,				maximum
		{PROPRIETARY_U8,				"U8",		1,		1,						0,								0,						MAX_U8},
		{PROPRIETARY_U16,				"U16",		2,		1,						0,								0,						MAX_U16},
		{PROPRIETARY_U32,				"U32",		4,		1,						0,								0,						MAX_U32},
		{PROPRIETARY_U64,				"U64",		8,		1,						0,								0,						(2^64)-1},
		{PROPRIETARY_2BYTE_FLOAT,		"float",	2,		1,						0,								float_IGNORE,			float_IGNORE},	// Generic 2-byte float
		{PROPRIETARY_4BYTE_FLOAT,		"float",	4,		1,						0,								float_IGNORE,			float_IGNORE},	// Generic 4-byte float
		{PROPRIETARY_GAIN1,			"Gain",		2,		MY_gain1_SCALING,		MY_gain1_OFFSET,				MY_gain1_OFFSET,		MY_gain1_OFFSET+(MY_gain1_SCALING*MAX_U16)},
		{PROPRIETARY_VOLT1,			"V",		2,		MY_volt1_SCALING,		MY_volt1_OFFSET,				MY_volt1_OFFSET,		MY_volt1_OFFSET+(MY_volt1_SCALING*MAX_U16)},
		{PROPRIETARY_CURRENT1,			"mA",		2,		MY_current1_SCALING,	MY_current1_OFFSET,			MY_current1_OFFSET,	MY_current1_OFFSET+(MY_current1_SCALING*MAX_U16)},
		{PROPRIETARY_PRESSURE_PSI,		"psi",		2,		MY_pressure_psi_SCALING,	MY_pressure_psi_OFFSET,	MY_pressure_psi_OFFSET,	MY_pressure_psi_OFFSET+(MY_pressure_psi_SCALING*MAX_U16)},
		{PROPRIETARY_PRESSURE_HG,		"Hg",		2,		MY_pressure_hg_SCALING,	MY_pressure_hg_OFFSET,		MY_pressure_hg_OFFSET,	MY_pressure_hg_OFFSET+(MY_pressure_hg_SCALING*MAX_U16)},
		{PROPRIETARY_TEXT,				"text",		8,		MY_text_SCALING,		MY_text_OFFSET,				float_IGNORE,			float_IGNORE},
		{PROPRIETARY_LAMBDA,			"lambda",	2,		EMTlambda_SCALING,		EMTlambda_OFFSET,				EMTlambda_OFFSET,		EMTlambda_OFFSET+(EMTlambda_SCALING*MAX_U16)},
		{PROPRIETARY_LAMBDA_OFFSET,	"spt off",	2,		EMTlambda_Off_SCALING,	EMTlambda_Off_OFFSET,			EMTlambda_Off_OFFSET,	EMTlambda_Off_OFFSET+(EMTlambda_Off_SCALING*MAX_U16)},
		{PROPRIETARY_STATUS,			"status",	1,		1,						0,								float_IGNORE,			float_IGNORE},
		{PROPRIETARY_SENSOR_TYPE,		"type",		1,		0,						0,								float_IGNORE,			float_IGNORE},
		{PROPRIETARY_BAUDRATE,			"baudrate",	1,		1,						0,								9600,					115200},	// Baudrate: 0=9600, 1=115.2k
		{PROPRIETARY_CLOSED_LOOP_STATUS,	"status",1,		1,						0,								float_IGNORE,			float_IGNORE},
		{PROPRIETARY_MS_TO_SECONDS,	"seconds",	1,		PROPRIETARY_MS2S_SCALING,		PROPRIETARY_MS2S_OFFSET,				PROPRIETARY_MS2S_OFFSET,		PROPRIETARY_MS2S_OFFSET+(PROPRIETARY_MS2S_SCALING*MAX_U16)},	// Seconds 0-62.5s
		{PROPRIETARY_SPN,				"SPN",		2,		1,						0,								0,						MAX_U16},
		{PROPRIETARY_TEMPERATURE,		"temp",		2,		SAEtp02_SCALING,		SAEtp02_OFFSET,					SAEtp02_OFFSET,			SAEtp02_OFFSET+(SAEtp02_SCALING*MAX_U16)},
		{PROPRIETARY_TEMPERATURE_OFFSET,"tempOff",	2,		SAEtp02_SCALING,		SAEtp02_OFFSET,					SAEtp02_OFFSET,			SAEtp02_OFFSET+(SAEtp02_SCALING*MAX_U16)},
		{PROPRIETARY_STRING,			"string",	6,		0,						0,								float_IGNORE,			float_IGNORE},
		{SAE_AD02,				"angle",	2,		SAEad02_SCALING,		SAEad02_OFFSET,					SAEad02_OFFSET,			SAEad02_OFFSET+(SAEad02_SCALING*MAX_U16)},
		{SAE_AD05,				"degree",	2,		SAEad05_SCALING,		SAEad05_OFFSET,					SAEad05_OFFSET,			SAEad05_OFFSET+(SAEad05_SCALING*MAX_U16)},
		{SAE_DS06,				"dist",		2,		SAEds06_SCALING,		SAEds06_OFFSET,					SAEds06_OFFSET,			SAEds06_OFFSET+(SAEds06_SCALING*MAX_U16)},
		{SAE_TP02,				"C",		2,		SAEtp02_SCALING,		SAEtp02_OFFSET,					SAEtp02_OFFSET,			SAEtp02_OFFSET+(SAEtp02_SCALING*MAX_U16)},
		{SAE_PC01,				"%",		2,		SAEpc01_SCALING,		SAEpc01_OFFSET,					SAEpc01_OFFSET,			SAEpc01_OFFSET+(SAEpc01_SCALING*MAX_U16)},
		{SAE_PC03,				"%",		1,		SAEpc03_SCALING,		SAEpc03_OFFSET,					SAEpc03_OFFSET,			SAEpc03_OFFSET+(SAEpc03_SCALING*MAX_U16)},
		{SAE_PC04,				"%",		1,		SAEpc04_SCALING,		SAEpc04_OFFSET,					SAEpc04_OFFSET,			SAEpc04_OFFSET+(SAEpc04_SCALING*MAX_U16)},
		{SAE_PC07,				"%",		2,		SAEpc07_SCALING,		SAEpc07_OFFSET,					SAEpc07_OFFSET,			SAEpc07_OFFSET+(SAEpc07_SCALING*MAX_U16)},
		{SAE_EV01,				"V",		2,		SAEev01_SCALING,		SAEev01_OFFSET,					SAEev01_OFFSET,			SAEev01_OFFSET+(SAEev01_SCALING*MAX_U16)},
		{SAE_TM02,				"seconds",	2,		SAEtm02_SCALING,		SAEtm02_OFFSET,					SAEtm02_OFFSET,			SAEtm02_OFFSET+(SAEtm02_SCALING*MAX_U16)},	// Seconds 0-64.255s
		{SAE_TM04,				"seconds",	1,		SAEtm04_SCALING,		SAEtm04_OFFSET,					SAEtm04_OFFSET,			SAEtm04_OFFSET+(SAEtm04_SCALING*MAX_U16)},	// Seconds 0-62.5s
		{SAE_TM05,				"seconds",	2,		0,						0,								0,						64255},					// Seconds 0-64255s
		{SAE_TM08,				"minutes",	1,		1,						0,								0,						59},					// Minutes
		{SAE_TM09,				"hours",	4,		SAEtm09_SCALING,		SAEtm09_OFFSET,					SAEtm09_OFFSET,			SAEtm09_OFFSET+(SAEtm09_SCALING*MAX_U32)},	// Hours 0.05/hr per bit
		{SAE_TM11,				"hour",		1,		1,						0,								0,						MAX_U8},				// Hours
		{SAE_CD01,				"day",		1,		0.25,					0,								0,						((2^8)/4)-1},			// Days
		{SAE_CM01,				"month",	1,		1,						0,								0,						MAX_U8},				// Month
		{SAE_CY01,				"year",		1,		1,						1985,							1985,					1985+MAX_U8},				// Year
		{SAE_VR01,				"rpm",		2,		SAEvr01_SCALING,		SAEvr01_OFFSET,					SAEvr01_OFFSET,			SAEvr01_OFFSET+(SAEvr01_SCALING*MAX_U16)},
		{SAE_VL02,				"kmh",		2,		SAEvl02_SCALING,		SAEvl02_OFFSET,					SAEvl02_OFFSET,			SAEvl02_OFFSET+(SAEvl02_SCALING*MAX_U16)},
		{SAE_CT05,				"ID",		2,		SAEct05_SCALING,		SAEct05_OFFSET,					SAEct05_OFFSET,			SAEct05_OFFSET+(SAEct05_SCALING*MAX_U16)},
		{SAE_RS01,				"ohms",		2,		SAErs01_SCALING,		SAErs01_OFFSET,					SAErs01_OFFSET,			SAErs01_OFFSET+(SAErs01_SCALING*MAX_U16)},
		{SAE_PP01,				"NOx",		2,		SAEpp01_SCALING,		SAEpp01_OFFSET,					SAEpp01_OFFSET,			SAEpp01_OFFSET+(SAEpp01_SCALING*MAX_U16)},
		{SAE_PC16,				"O2",		2,		SAEpc16_SCALING,		SAEpc16_OFFSET,					SAEpc16_OFFSET,			SAEpc16_OFFSET+(SAEpc16_SCALING*MAX_U16)},
		{PROPRIETARY_NOX_SENSOR_STATUS,"NOx Stat",	1,		1,						0,								0,						MAX_U8},
		{PROPRIETARY_NOX_HEATER_STATUS,"Htr Stat",	1,		1,						0,								0,						MAX_U8},
		{PROPRIETARY_NOX_FMI,			"NOx FMI",	1,		1,						0,								0,						MAX_U8},
		{PROPRIETARY_O2_FMI,			"O2 FMI",	1,		1,						0,								0,						MAX_U8},
		{PROPRIETARY_DEW_POINT,		"Dew Pt",	1,		1,						0,								0,						MAX_U8},
		{PROPRIETARY_CONTROL_STATUS,	"status",	1,		1,						0,								float_IGNORE,			float_IGNORE},
		{PROPRIETARY_SENSOR_STATUS,	"status",	1,		1,						0,								float_IGNORE,			float_IGNORE},
		{PROPRIETARY_MULTISETPOINT_CONFIG, "cfg",	1,		1,						0,								float_IGNORE,			float_IGNORE},
		{PROPRIETARY_MULTISETPOINT_SETUP, "setup", 6,		1,						0,								float_IGNORE,			float_IGNORE},
	};
	const int NUMBER_OF_SLOTS = sizeof(slotTable)/sizeof(slotType);
#else
	extern const int NUMBER_OF_SLOTS;
	extern const slotType slotTable[];
#endif

//-------------------------------------------------------------------------------------------------
// Typedef's to support the above SLOT table formats
//-------------------------------------------------------------------------------------------------
// This type is defined by 8 bits
typedef enum {
	MST_DISABLED,
	MST_ENABLED,
	MST_DELETE_TABLE,						// Delete the table
	MST_ADD_INPUT,
	MST_ADD_OFFSET,
} multisetpointConfigEnumType;

//------------------------------------------------------------------
// 6 Bytes
//------------------------------------------------------------------
//    0                    1    2-3,    4-5
//------------------------------------------------------------------
// CODE, SensorType/Bank/Row, Input, Offset
//------------------------------------------------------------------
typedef enum {
	MST_CODE_VIEW,			// 0: Updates the shadow table.  Bank, Row, Input, and Offset are ignored.
	MST_CODE_ENABLE,		// 1: Bank, Row, Input, and Offset are ignored
	MST_CODE_DISABLE,		// 2: Bank, Row, Input, and Offset are ignored
	MST_CODE_ADD_ENTRY,		// 3: Data field contains Input and Offset
	MST_CODE_DELETE_ENTRY,	// 4: Input and Offset are ignored
	MST_CODE_DELETE_TABLE,	// 5: Bank, Row, Input, and Offset are ignored
} codeEnumType;

typedef enum {
	LEFT_BANK,
	RIGHT_BANK,
} bankEnumType;

typedef enum {
	MST_MANIFOLD_PRESSURE_LEFT_BANK_1,
	MST_MANIFOLD_PRESSURE_RIGHT_BANK_2,
	MST_AUXILARY_TEMPERATURE_1,
	MST_AMBIENT_TEMPERATURE_THERMISTOR,
	MST_ENGINE_SPEED,
	MST_WIDEBAND_LAMBDA_POSTCAT,
	MST_ANALOG_CURRENT_1,
	MST_ANALOG_VOLTAGE_1,
} sensorEnumType;

// This structure can be no more than 6 bytes in length
#define USE_INCREMENTING_ORDER
#ifdef USE_INCREMENTING_ORDER
	typedef struct {
		U8 code;			// 0
		union {
			struct {
				U8 sensorType:4;	// 1.0 to 1.3
				U8 bank:1;			// 1.4
				U8 row:3;			// 1.5 to 1.7
			} split;
			U8 configByte;
		} u;
		U16 input;			// 2-3
		U16 offset;			// 4-5
	} mstSetupType;
#else
	typedef struct {
		U16 offset;			// 4-5
		U16 input;			// 2-3
		U8 sensorType:4;	// 1.0 to 1.3
		U8 bank:1;			// 1.4
		U8 row:3;			// 1.5 to 1.7
		U8 code;			// 0
	} mstSetupType;
#endif

typedef enum {
	CONTROL_STATUS_NO_ERROR,

	// Errors
	CONTROL_STATUS_ERROR_BANK_1 = 0x80,
	CONTROL_STATUS_ERROR_BANK_2,
	CONTROL_STATUS_ERROR_BANKS_1_AND_2,
	CONTROL_STATUS_ERROR_UNKNOWN,
} controlStatusEnumType;

// This status is used for both Narrowband and Wideband sensors
typedef enum {
	// Status
	SENSOR_STATUS_IS_NOT_ENABLED,
	SENSOR_STATUS_NO_ERROR,
	SENSOR_STATUS_HEATER_WARMUP,			// Voltage has been applied but the heater is not yet warm
	SENSOR_STATUS_READY,					// The heater is warm but control is not enabled
	SENSOR_STATUS_ATTEMPTING_TO_CONTROL,	// The PID loop is trying to control but the lamda/Vs readings are outside the limits
	SENSOR_STATUS_SENSOR_IS_CONTROLLED,		// DPV is controlling around the setpoint using the readings from the sensor

	SENSOR_STATUS_CONTROL_DELAY,			// Auto Mode is enabled but control is in a delay loop
	SENSOR_STATUS_SETPOINT_CONTROL,			// AutoControl startup state
	SENSOR_STATUS_AUTOCONTROL,				// AutoControl is active

	// Errors
	SENSOR_STATUS_ERROR_FAILED_LEAN = 0x80,
	SENSOR_STATUS_ERROR_FAILED_RICH,
	SENSOR_STATUS_ERROR_INVALID_READINGS,
	SENSOR_STATUS_ERROR_HEATER_FAILURE,		// AFRC wasn't able to control the heater resistance - WIDEBAND only
	SENSOR_STATUS_ERROR_UNKNOWN,

	// Declare this error if either Pre or Post catalyst temperature is higher than 1250F for 60 seconds
	SENSOR_STATUS_ERROR_CATALYST_OVERTEMPERATURE,
} sensorStatusEnumType;

//-------------------------------------------------------------------------------------------------
// SPN Table - lists size and scaling of each SPN so that it can be inserted into a PGN
//-------------------------------------------------------------------------------------------------
typedef struct {
	spnEnumType spn;
	slotEnumType slotIdentifier;
} spnType;

#ifdef GLOBAL
	// Not in any particular order.
	const spnType spnMasterTable[] = {
		{SPN_EXHAUST_TEMPERATURE_PRECAT,				PROPRIETARY_TEMPERATURE},
		{SPN_EXHAUST_TEMPERATURE_POSTCAT,				PROPRIETARY_TEMPERATURE},
		{SPN_REG_PRECAT_TEMPERATURE_4_HOUR_AVERAGE,		PROPRIETARY_TEMPERATURE},
		{SPN_REG_DIFFERENTIAL_PRESSURE_15_MINUTE_AVERAGE,PROPRIETARY_CURRENT1},
		{SPN_EXHAUST_DIFFERENTIAL_TEMPERATURE,			PROPRIETARY_TEMPERATURE_OFFSET},
		{SPN_AMBIENT_TEMPERATURE,						PROPRIETARY_TEMPERATURE},
		{SPN_AMBIENT_TEMPERATURE_THERMISTOR,			PROPRIETARY_TEMPERATURE},
		{SPN_FUEL_TEMPERATURE_THERMISTOR,				PROPRIETARY_TEMPERATURE},
		{SPN_ENGINE_AIR_INTAKE_TEMPERATURE,				PROPRIETARY_TEMPERATURE},
		{SPN_FUEL_TEMPERATURE,							PROPRIETARY_TEMPERATURE},
		{SPN_ENGINE_FUEL_TEMPERATURE_LEFT_BANK_1,		PROPRIETARY_TEMPERATURE},
		{SPN_ENGINE_FUEL_TEMPERATURE_RIGHT_BANK_2,		PROPRIETARY_TEMPERATURE},
		{SPN_AUXILARY_TEMPERATURE_1,					PROPRIETARY_TEMPERATURE},
		{SPN_AUXILARY_TEMPERATURE_2,					PROPRIETARY_TEMPERATURE},
		{SPN_BATTERY_POTENTIAL,							SAE_EV01},
		{SPN_ENGINE_SPEED,								SAE_VR01},
		{SPN_DPV_DESIRED_POSITION_LEFT_BANK_1_STEPS,	PROPRIETARY_U16},
		{SPN_DPV_ACTUAL_POSITION_LEFT_BANK_1_STEPS,		PROPRIETARY_U16},
		{SPN_DPV_DESIRED_POSITION_RIGHT_BANK_2_STEPS,	PROPRIETARY_U16},
		{SPN_DPV_ACTUAL_POSITION_RIGHT_BANK_2_STEPS,	PROPRIETARY_U16},
		{SPN_DPV_DESIRED_POSITION_LEFT_BANK_1,			SAE_PC01},
		{SPN_DPV_ACTUAL_POSITION_LEFT_BANK_1,			SAE_PC01},
		{SPN_DPV_DESIRED_POSITION_RIGHT_BANK_2,			SAE_PC01},
		{SPN_DPV_ACTUAL_POSITION_RIGHT_BANK_2,			SAE_PC01},
		{SPN_PROPRIETARY_SERIAL_NUMBER,						PROPRIETARY_U32},
		{SPN_HARDWARE_ID,								SAE_CT05},
		{SPN_APPLICATION_ID,							SAE_CT05},
		{SPN_ECU_UPTIME,								SAE_TM09},
		{SPN_ECU_RUNTIME,								SAE_TM09},
		{SPN_ENGINE_UPTIME,								SAE_TM09},
		{SPN_ENGINE_RUNTIME,							SAE_TM09},
		{SPN_ANALOG_VOLTAGE_1,							PROPRIETARY_VOLT1},
		{SPN_ANALOG_CURRENT_1,							PROPRIETARY_CURRENT1},
		{SPN_ANALOG_VOLTAGE_2,							PROPRIETARY_VOLT1},
		{SPN_ANALOG_CURRENT_2,							PROPRIETARY_CURRENT1},
		{SPN_ANALOG_VOLTAGE_3,							PROPRIETARY_VOLT1},
		{SPN_ANALOG_CURRENT_3,							PROPRIETARY_CURRENT1},
		{SPN_ANALOG_VOLTAGE_4,							PROPRIETARY_VOLT1},
		{SPN_ANALOG_CURRENT_4,							PROPRIETARY_CURRENT1},
		{SPN_ANALOG_VOLTAGE_5,							PROPRIETARY_VOLT1},
		{SPN_ANALOG_CURRENT_5,							PROPRIETARY_CURRENT1},
		{SPN_ANALOG_VOLTAGE_6,							PROPRIETARY_VOLT1},
		{SPN_ANALOG_CURRENT_6,							PROPRIETARY_CURRENT1},
		{SPN_ANALOG_VOLTAGE_7,							PROPRIETARY_VOLT1},
		{SPN_ANALOG_CURRENT_7,							PROPRIETARY_CURRENT1},
		{SPN_ANALOG_VOLTAGE_8,							PROPRIETARY_VOLT1},
		{SPN_ANALOG_CURRENT_8,							PROPRIETARY_CURRENT1},
		{SPN_ANALOG_VOLTAGE_9,							PROPRIETARY_VOLT1},
		{SPN_ANALOG_CURRENT_9,							PROPRIETARY_CURRENT1},
		{SPN_ANALOG_VOLTAGE_10,							PROPRIETARY_VOLT1},
		{SPN_ANALOG_CURRENT_10,							PROPRIETARY_CURRENT1},
		{SPN_CAT_PRESSURE_VOLTAGE,						PROPRIETARY_VOLT1},
		{SPN_CAT_PRESSURE_CURRENT,						PROPRIETARY_CURRENT1},
		{SPN_FUELFLOW_VOLTAGE,							PROPRIETARY_VOLT1},
		{SPN_FUELFLOW_CURRENT,							PROPRIETARY_CURRENT1},
		{SPN_MANIFOLD_PRESSURE_LEFT_BANK_1,				PROPRIETARY_CURRENT1},
		{SPN_MANIFOLD_PRESSURE_RIGHT_BANK_2,			PROPRIETARY_CURRENT1},
		{SPN_NARROWBAND_VOLTAGE_LEFT_BANK_1,			PROPRIETARY_VOLT1},
		{SPN_NARROWBAND_VOLTAGE_RIGHT_BANK_2,			PROPRIETARY_VOLT1},
		{SPN_NARROWBAND_VOLTAGE_POSTCAT,				PROPRIETARY_VOLT1},
		{SPN_HEATER_DUTY_CYCLE_BANK_1,					SAE_PC01},
		{SPN_HEATER_CONTROL_TIME_BANK_1,				PROPRIETARY_MS_TO_SECONDS},
		{SPN_HEATER_PID_STATE_BANK_1,					PROPRIETARY_U8},
		{SPN_HEATER_PID_ENABLED_BANK_1,					PROPRIETARY_U8},
		{SPN_HEATER_DUTY_CYCLE_BANK_2,					SAE_PC01},
		{SPN_HEATER_CONTROL_TIME_BANK_2,				PROPRIETARY_MS_TO_SECONDS},
		{SPN_HEATER_PID_STATE_BANK_2,					PROPRIETARY_U8},
		{SPN_HEATER_PID_ENABLED_BANK_2,					PROPRIETARY_U8},
		{SPN_HEATER_DUTY_CYCLE_POSTCAT,					SAE_PC01},
		{SPN_HEATER_CONTROL_TIME_POSTCAT,				PROPRIETARY_MS_TO_SECONDS},
		{SPN_HEATER_PID_STATE_POSTCAT,					PROPRIETARY_U8},
		{SPN_HEATER_PID_ENABLED_POSTCAT,				PROPRIETARY_U8},
		{SPN_PID_RESPONSE_TIME_LEFT_BANK_1,				SAE_PC01},
		{SPN_PID_RESPONSE_TIME_RIGHT_BANK_2,			SAE_PC01},

		{SPN_SECONDS,									SAE_TM04},
		{SPN_MINUTES,									SAE_TM08},
		{SPN_HOURS,										SAE_TM11},
		{SPN_DAY,										SAE_CD01},
		{SPN_MONTH,										SAE_CM01},
		{SPN_YEAR,										SAE_CY01},
		{SPN_SETPOINT_OFFSET,							PROPRIETARY_LAMBDA_OFFSET},
		{SPN_WIDEBAND_LAMBDA_LEFT_BANK_1,				PROPRIETARY_LAMBDA},
		{SPN_WIDEBAND_LAMBDA_RIGHT_BANK_2,				PROPRIETARY_LAMBDA},
		{SPN_WIDEBAND_LAMBDA_POSTCAT,					PROPRIETARY_LAMBDA},
		{SPN_WIDEBAND_NERNST_CELL_RESISTANCE_LEFT_BANK_1,		SAE_RS01},
		{SPN_WIDEBAND_NERNST_CELL_RESISTANCE_RIGHT_BANK_2,		SAE_RS01},
		{SPN_WIDEBAND_NERNST_CELL_RESISTANCE_POSTCAT,			SAE_RS01},
		{SPN_EXHAUST_GAS_SENSOR_IS_AT_TEMPERATURE_LEFT_BANK_1,	PROPRIETARY_STATUS},
		{SPN_EXHAUST_GAS_SENSOR_IS_AT_TEMPERATURE_RIGHT_BANK_2,	PROPRIETARY_STATUS},
		{SPN_O2_SENSOR_CLOSED_LOOP_OPERATION_LEFT_BANK_1,		PROPRIETARY_CLOSED_LOOP_STATUS},
		{SPN_O2_SENSOR_CLOSED_LOOP_OPERATION_RIGHT_BANK_2,		PROPRIETARY_CLOSED_LOOP_STATUS},
		{SPN_O2_READING_IS_STABLE_LEFT_BANK_1,			PROPRIETARY_STATUS},
		{SPN_O2_READING_IS_STABLE_RIGHT_BANK_2,			PROPRIETARY_STATUS},
		{SPN_SENSOR_STATUS_LEFT_BANK_1_1,				PROPRIETARY_U8},
		{SPN_SENSOR_STATUS_RIGHT_BANK_2_1,				PROPRIETARY_U8},
		{SPN_SENSOR_STATUS_POSTCAT_1,					PROPRIETARY_U8},
		{SPN_SENSOR_STATUS_LEFT_BANK_1_2,				PROPRIETARY_U8},
		{SPN_SENSOR_STATUS_RIGHT_BANK_2_2,				PROPRIETARY_U8},
		{SPN_SENSOR_STATUS_POSTCAT_2,					PROPRIETARY_U8},

		// Configuration SPN's
		{SPN_AUTO_MANUAL_MODE,							PROPRIETARY_U8},
		{SPN_SINGLE_OR_DUAL_BANK,						PROPRIETARY_U8},
		{SPN_RUN_SIGNAL,								PROPRIETARY_U8},
		{SPN_USE_POST_CATALYST_SENSOR,					PROPRIETARY_U8},
		{SPN_ERROR_RELAY,								PROPRIETARY_U8},
		{SPN_NUMBER_OF_TEETH_ON_FLYWHEEL,				PROPRIETARY_U16},
		{SPN_DISCRETE_INPUT,							PROPRIETARY_U8},
		{SPN_OIL_PRESSURE_SWITCH,						PROPRIETARY_U8},
		{SPN_TEMPERATURE_CONFIG_C_OR_F,					PROPRIETARY_U8},
		{SPN_AUTOSTART_DELAY,							PROPRIETARY_U16},
		{SPN_ENABLE_AUTOCONTROL_MODE,					PROPRIETARY_U8},

		// Left
		{SPN_LEFT_WIDEBAND_LAMBDA_SETPOINT,				PROPRIETARY_LAMBDA},
		{SPN_LEFT_NARROWBAND_VOLTAGE_SETPOINT,			PROPRIETARY_VOLT1},
		{SPN_LEFT_WIDEBAND_KP,							PROPRIETARY_GAIN1},
		{SPN_LEFT_WIDEBAND_KI,							PROPRIETARY_GAIN1},
		{SPN_LEFT_WIDEBAND_KD,							PROPRIETARY_GAIN1},
		{SPN_LEFT_NARROWBAND_KP,						PROPRIETARY_GAIN1},
		{SPN_LEFT_NARROWBAND_KI,						PROPRIETARY_GAIN1},
		{SPN_LEFT_NARROWBAND_KD,						PROPRIETARY_GAIN1},
		{SPN_LEFT_NERNST_KP,							PROPRIETARY_GAIN1},
		{SPN_LEFT_NERNST_KI,							PROPRIETARY_GAIN1},
		{SPN_LEFT_NERNST_KD,							PROPRIETARY_GAIN1},
		{SPN_LEFT_BANK_ENABLED,							PROPRIETARY_U8},

		// Right
		{SPN_RIGHT_WIDEBAND_LAMBDA_SETPOINT,			PROPRIETARY_LAMBDA},
		{SPN_RIGHT_NARROWBAND_VOLTAGE_SETPOINT,			PROPRIETARY_VOLT1},
		{SPN_RIGHT_WIDEBAND_KP,							PROPRIETARY_GAIN1},
		{SPN_RIGHT_WIDEBAND_KI,							PROPRIETARY_GAIN1},
		{SPN_RIGHT_WIDEBAND_KD,							PROPRIETARY_GAIN1},
		{SPN_RIGHT_NARROWBAND_KP,						PROPRIETARY_GAIN1},
		{SPN_RIGHT_NARROWBAND_KI,						PROPRIETARY_GAIN1},
		{SPN_RIGHT_NARROWBAND_KD,						PROPRIETARY_GAIN1},
		{SPN_RIGHT_NERNST_KP,							PROPRIETARY_GAIN1},
		{SPN_RIGHT_NERNST_KI,							PROPRIETARY_GAIN1},
		{SPN_RIGHT_NERNST_KD,							PROPRIETARY_GAIN1},
		{SPN_RIGHT_BANK_ENABLED,						PROPRIETARY_U8},

		// Post Catalyst
		{SPN_POSTCAT_WIDEBAND_LAMBDA_SETPOINT,			PROPRIETARY_LAMBDA},
		{SPN_POSTCAT_NARROWBAND_VOLTAGE_SETPOINT,		PROPRIETARY_VOLT1},
		{SPN_POSTCAT_WIDEBAND_KP,						PROPRIETARY_GAIN1},
		{SPN_POSTCAT_WIDEBAND_KI,						PROPRIETARY_GAIN1},
		{SPN_POSTCAT_WIDEBAND_KD,						PROPRIETARY_GAIN1},
		{SPN_POSTCAT_NARROWBAND_KP,						PROPRIETARY_GAIN1},
		{SPN_POSTCAT_NARROWBAND_KI,						PROPRIETARY_GAIN1},
		{SPN_POSTCAT_NARROWBAND_KD,						PROPRIETARY_GAIN1},
		{SPN_POSTCAT_NERNST_KP,							PROPRIETARY_GAIN1},
		{SPN_POSTCAT_NERNST_KI,							PROPRIETARY_GAIN1},
		{SPN_POSTCAT_NERNST_KD,							PROPRIETARY_GAIN1},
		{SPN_POSTCAT_ENABLED,							PROPRIETARY_U8},

		{SPN_CALIBRATE_DPV_HOME_POSITION,				PROPRIETARY_U8},
		{SPN_HOME_POSITION_CALIBRATION_COUNTER,			PROPRIETARY_U16},

		{SPN_MINIMUM_RPM,								SAE_VR01},
		{SPN_MAXIMUM_RPM,								SAE_VR01},
		{SPN_MINIMUM_EXHAUST_TEMPERATURE,				PROPRIETARY_TEMPERATURE},
		{SPN_MAXIMUM_EXHAUST_TEMPERATURE,				PROPRIETARY_TEMPERATURE},
		{SPN_O2_SENSOR_WARMUP_TIME_S,					SAE_TM05},
		{SPN_O2_SENSOR_TYPE,							PROPRIETARY_U8},
		{SPN_O2_SENSOR_ERROR_TIME,						PROPRIETARY_U8},
		{SPN_FILESYSTEM_UPDATE_PERIOD_S,				SAE_TM05},
		{SPN_DATALOGGING_PERIOD_S,						SAE_TM05},
		{SPN_ANALOG_1_IS_4_20MA,						PROPRIETARY_STATUS},
		{SPN_ANALOG_2_IS_4_20MA,						PROPRIETARY_STATUS},
		{SPN_ANALOG_3_IS_4_20MA,						PROPRIETARY_STATUS},
		{SPN_ANALOG_4_IS_4_20MA,						PROPRIETARY_STATUS},
		{SPN_ANALOG_5_IS_4_20MA,						PROPRIETARY_STATUS},
		{SPN_ANALOG_6_IS_4_20MA,						PROPRIETARY_STATUS},
		{SPN_ANALOG_7_IS_4_20MA,						PROPRIETARY_STATUS},
		{SPN_ANALOG_8_IS_4_20MA,						PROPRIETARY_STATUS},
		{SPN_ANALOG_9_IS_4_20MA,						PROPRIETARY_STATUS},
		{SPN_ANALOG_10_IS_4_20MA,						PROPRIETARY_STATUS},
		{SPN_MANIFOLD_PRESSURE_RIGHT_IS_4_20MA,			PROPRIETARY_STATUS},
		{SPN_MANIFOLD_PRESSURE_LEFT_IS_4_20MA,			PROPRIETARY_STATUS},
		{SPN_RS232_RS485_BAUD_RATE,						PROPRIETARY_BAUDRATE},
		{SPN_O2_SENSOR_WARMUP_TIME_S,					SAE_TM05},
		{SPN_STARTUP_WAIT_TIME,							SAE_TM05},
		{SPN_DPV_HOME_POSITION,							SAE_PC01},
		{SPN_LED_INDICATORS,							SAE_CT05},
		{SPN_DTC_STATUS_LEDS,							PROPRIETARY_U16},
		{SPN_DTC_SPN,									PROPRIETARY_U32},

		// Multi-setpoint tables - hides the fact that several tables exist in the AFRC
		{SPN_MULTISETPOINT_TABLE_SETUP,					PROPRIETARY_MULTISETPOINT_SETUP},
		{SPN_MULTISETPOINT_TABLE_CONFIG,				PROPRIETARY_MULTISETPOINT_CONFIG},
		{SPN_MULTISETPOINT_TABLE_LEFT_OR_RIGHT,			PROPRIETARY_U8},
		{SPN_MULTISETPOINT_TABLE_SOURCE,				PROPRIETARY_SPN},
		{SPN_MULTISETPOINT_TABLE_ENTRY_0_INPUT,			PROPRIETARY_CURRENT1},
		{SPN_MULTISETPOINT_TABLE_ENTRY_0_OFFSET,		PROPRIETARY_LAMBDA_OFFSET},
		{SPN_MULTISETPOINT_TABLE_ENTRY_1_INPUT,			PROPRIETARY_CURRENT1},
		{SPN_MULTISETPOINT_TABLE_ENTRY_1_OFFSET,		PROPRIETARY_LAMBDA_OFFSET},
		{SPN_MULTISETPOINT_TABLE_ENTRY_2_INPUT,			PROPRIETARY_CURRENT1},
		{SPN_MULTISETPOINT_TABLE_ENTRY_2_OFFSET,		PROPRIETARY_LAMBDA_OFFSET},
		{SPN_MULTISETPOINT_TABLE_ENTRY_3_INPUT,			PROPRIETARY_CURRENT1},
		{SPN_MULTISETPOINT_TABLE_ENTRY_3_OFFSET,		PROPRIETARY_LAMBDA_OFFSET},
		{SPN_MULTISETPOINT_TABLE_ENTRY_4_INPUT,			PROPRIETARY_CURRENT1},
		{SPN_MULTISETPOINT_TABLE_ENTRY_4_OFFSET,		PROPRIETARY_LAMBDA_OFFSET},
		{SPN_MULTISETPOINT_TABLE_ROW_0_ENABLED,			PROPRIETARY_U8},
		{SPN_MULTISETPOINT_TABLE_ROW_1_ENABLED,			PROPRIETARY_U8},
		{SPN_MULTISETPOINT_TABLE_ROW_2_ENABLED,			PROPRIETARY_U8},
		{SPN_MULTISETPOINT_TABLE_ROW_3_ENABLED,			PROPRIETARY_U8},
		{SPN_MULTISETPOINT_TABLE_ROW_4_ENABLED,			PROPRIETARY_U8},

		{SPN_AFRC_CONTROL_STATUS,						PROPRIETARY_CONTROL_STATUS},
		{SPN_AFRC_CONTROL_STATUS_BANK_1,				PROPRIETARY_SENSOR_STATUS},
		{SPN_AFRC_CONTROL_STATUS_BANK_2,				PROPRIETARY_SENSOR_STATUS},
		{SPN_AFRC_CONTROL_STATUS_POSTCAT,				PROPRIETARY_SENSOR_STATUS},

		{SPN_EXHAUST_TEMPERATURE_PRECAT_GAIN,			PROPRIETARY_GAIN1},
		{SPN_EXHAUST_TEMPERATURE_PRECAT_OFFSET,			PROPRIETARY_TEMPERATURE_OFFSET},
		{SPN_EXHAUST_TEMPERATURE_POSTCAT_GAIN,			PROPRIETARY_GAIN1},
		{SPN_EXHAUST_TEMPERATURE_POSTCAT_OFFSET,		PROPRIETARY_TEMPERATURE_OFFSET},

		// Production Test
		{SPN_PRODUCTION_TEST_STATE_SLAVE,				PROPRIETARY_U8},
		{SPN_PRODUCTION_TEST_STATE_MASTER,				PROPRIETARY_U8},
		{SPN_PRODUCTION_TEST_SELECT_DPV,				PROPRIETARY_U8},
		{SPN_PRODUCTION_TEST_SET_DPV_PHASE,				PROPRIETARY_U8},
		{SPN_PRODUCTION_TEST_SELECT_HEATER,				PROPRIETARY_U8},
		{SPN_PRODUCTION_TEST_SET_SENSOR_HEATER_PWM,		SAE_PC01},
		{SPN_PRODUCTION_TARGET_TEMPERATURE,				PROPRIETARY_TEMPERATURE},
		{SPN_PRODUCTION_OK_TO_CALIBRATE,				PROPRIETARY_U8},
		{SPN_PRODUCTION_CALIBRATED,						PROPRIETARY_U8},

		// 2012/05/21 Added
		{SPN_RAW_ADC_NERNST_1,							PROPRIETARY_VOLT1},
		{SPN_RAW_ADC_WIDEBAND_1,						PROPRIETARY_VOLT1},
		{SPN_RAW_ADC_NARROWBAND_1,						PROPRIETARY_VOLT1},
		{SPN_RAW_ADC_NERNST_2,							PROPRIETARY_VOLT1},
		{SPN_RAW_ADC_WIDEBAND_2,						PROPRIETARY_VOLT1},
		{SPN_RAW_ADC_NARROWBAND_2,						PROPRIETARY_VOLT1},
		{SPN_RAW_ADC_NERNST_POSTCAT,					PROPRIETARY_VOLT1},
		{SPN_RAW_ADC_WIDEBAND_POSTCAT,					PROPRIETARY_VOLT1},
		{SPN_RAW_ADC_NARROWBAND_POSTCAT,				PROPRIETARY_VOLT1},
		{SPN_DATATAG_STATUS_ENGINE,						PROPRIETARY_U8},
		{SPN_DATATAG_STATUS_COOLER,						PROPRIETARY_U8},
		{SPN_DATATAG_STATUS_COMPRESSOR,					PROPRIETARY_U8},

		// 2012/09/20 Added
		{SPN_NOX,										SAE_PP01},
		{SPN_O2,										SAE_PC16},
		{SPN_NOX_SENSOR_STATUS,							PROPRIETARY_NOX_SENSOR_STATUS},
		{SPN_NOX_HEATER,								PROPRIETARY_NOX_HEATER_STATUS},
		{SPN_NOX_ERROR,									PROPRIETARY_NOX_FMI},
		{SPN_O2_ERROR,									PROPRIETARY_O2_FMI},
		{SPN_DEW_POINT,									PROPRIETARY_DEW_POINT},

		// 2013-01-31 Added
		{SPN_AUTOCONTROL_ADJUSTMENT,					SAE_PC01},
		{SPN_AUTOCONTROL_MINIMUM_POSTCAT_VOLTS,			PROPRIETARY_VOLT1},
		{SPN_AUTOCONTROL_TARGET_AQUISITION_TIME,		SAE_TM02},
		{SPN_AUTOCONTROL_TARGET_HOLD_TIME,				SAE_TM02},

		{SPN_NAVIGATION_BASED_VEHICLE_SPEED,			SAE_VL02},
		{SPN_TACHOGRAPH_VEHICLE_SPEED,					SAE_VL02},
		{SPN_OUTPUT_SHAFT_SPEED,						SAE_VR01},
		{SPN_ALTITUDE,									SAE_DS06},
		{SPN_PITCH,										SAE_AD02},
		{SPN_COMPASS_BEARING,							SAE_AD05},

		// 2013-07-22 Added
		{SPN_X,											PROPRIETARY_U8},
		{SPN_Y,											PROPRIETARY_U8},
		{SPN_STRING,									PROPRIETARY_STRING},

		// Blank unused SPN's
		{SPN_UNUSED_8,									PROPRIETARY_U8},
		{SPN_UNUSED_16,									PROPRIETARY_U16},
		{SPN_UNUSED_32,									PROPRIETARY_U32},
	};
	const int NUMBER_OF_SPNS_IN_MASTER_TABLE = sizeof(spnMasterTable)/sizeof(spnType);
#else
	extern const spnType spnMasterTable[];
	extern const int NUMBER_OF_SPNS_IN_MASTER_TABLE;
#endif	// GLOBAL

#endif	// _SPN_H

// Last Line

